﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using PSE.Framework.ProviderLoader;
using PSE.Framework.ProviderLoader.Configuration;
using PSE.Framework.Configuration;
using PSE.Framework.UI.Settings;

namespace Sinacor.Infra.UI.Settings.Providers
{
    public class LocalConfigurationSettingsHandler : BaseProvider, IConfigurationSettingsHandler<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>
    {
        private const string FILE_EXTENSION = "*.xml";

        private const string FILE_PATH = @"\Sinacor\Settings\";

        private const string LOCAL_SETTINGS_PROVIDER = "localSettingsProvider";

        private const string CONFIG_SECTION_NAME = "clientProviders";

        public LocalConfigurationSettingsHandler(ProviderConfigurationElement configuration)
            : base(configuration)
        {

        }

        private string GetPath(SinacorConfigurationObjectType configurationType)
        {
            string path = string.Format(@"{0}{1}", System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), FILE_PATH);
            path += configurationType.ToString() + @"\";
            return path;
        }


        private bool SaveSettings(IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> configuration)
        {
            ProviderConfigurationSection configSection = ApplicationConfiguration.GetCurrent().GetSection<ProviderConfigurationSection>(CONFIG_SECTION_NAME);

            IConfigurationSettings<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> settings = ProviderLoader<IConfigurationSettings<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>>.LoadProvider(configSection.Providers, LOCAL_SETTINGS_PROVIDER);

            return settings.Save(configuration);
        }

        public bool ChangePropertyValue<T>(IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> configuration, string propertyName, object value) where T : IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>
        {

            Type typeT = typeof(T);

            PropertyInfo prop = typeT.GetProperty(propertyName);

            if (prop != null)
            {
                prop.SetValue(configuration, value, null);
                return this.SaveSettings(configuration);
            }

            return false;

        }

        public void ChangeAllPropertiesValue<T>(SinacorConfigurationObjectType configurationType, string propertyName, object value) where T : IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>, new()
        {
            List<IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>> listConfigObject = this.GetConfigurationObjects<T>(configurationType);

            if (listConfigObject != null)
            {
                foreach (IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> config in listConfigObject)
                {
                    this.ChangePropertyValue<T>(config, propertyName, value); 
                }
            }
        }


        public List<IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>> GetConfigurationObjects<T>(SinacorConfigurationObjectType configurationType) where T : IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>, new() 
        {
            List<IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>> listConfigObject = new List<IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>>();

            string path = this.GetPath(configurationType);

            if (System.IO.Directory.Exists(path))
            {
                string[] fileList = System.IO.Directory.GetFiles(path, FILE_EXTENSION);

                ProviderConfigurationSection configSection = ApplicationConfiguration.GetCurrent().GetSection<ProviderConfigurationSection>(CONFIG_SECTION_NAME);

                IConfigurationSettings<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> settings = ProviderLoader<IConfigurationSettings<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType>>.LoadProvider(configSection.Providers, LOCAL_SETTINGS_PROVIDER);

                foreach (string file in fileList)
                {
                    IConfigurationObject<Sinacor.Infra.UI.Settings.SinacorConfigurationObjectType> configObject = new T();
                    System.IO.FileInfo fileInfo = new System.IO.FileInfo(file);
                    configObject.ConfigurationName = fileInfo.Name.Replace(fileInfo.Extension, ""); 
                    configObject.ConfigurationType = configurationType;
 
                    if (settings.Load(ref configObject))
                    {
                        listConfigObject.Add(configObject);
                    }

                }

                settings = null;
            }

            if (listConfigObject.Count > 0)
                return listConfigObject;
            else
                return null;
        }


    }
}
